/*
    Find Volume 
    @5mukx
*/

use std::{ffi::OsString, os::windows::ffi::OsStringExt, ptr::null_mut};

use winapi::um::{errhandlingapi::GetLastError, fileapi::{FindFirstVolumeW, FindNextVolumeW, FindVolumeClose, GetVolumePathNamesForVolumeNameW}};

pub(crate) fn get_all_volumes() -> Vec<OsString>{

    let mut drive_letters = Vec::new();
    let mut volume_name: [u16; 260] = [0; 260];
    let mut path_name: [u16; 260] = [0; 260];

    unsafe{
        let volume_handle = FindFirstVolumeW(
            volume_name.as_mut_ptr(),
            260 as u32,
        );

        if volume_handle != null_mut(){
            loop{
                // let name_length = volume_name.iter().position(|&c| c == 0).unwrap_or(260);

                let result = GetVolumePathNamesForVolumeNameW(
                    volume_name.as_ptr(),
                    path_name.as_mut_ptr(),
                    260 as u32,
                    null_mut(),
                );

                if result != 0{
                    let mut start = 0;

                    while start < 260 {
                        let path_name_length = path_name[start..].iter().position(|&c| c == 0).unwrap_or(260);

                        if path_name_length == 0{
                            break;
                        }

                        let path_name = OsString::from_wide(&path_name[start..start + path_name_length]);

                        if !path_name.to_string_lossy().starts_with("C:\\") && !path_name.to_string_lossy().is_empty(){
                            drive_letters.push(path_name);
                        }

                        start += path_name_length + 1;

                    }
                }
                let find_next_volume = FindNextVolumeW(
                    volume_handle, 
                    volume_name.as_mut_ptr(),
                    260 as u32
                );

                if find_next_volume == 0{
                    if GetLastError() == 18{
                        break;
                    }
                }
            }
            FindVolumeClose(volume_handle);
        }
    }
    // At last return the drive letter 
    drive_letters

}